home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
pascal
/
wctunits.zip
/
XCRT.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1991-07-30
|
17KB
|
589 lines
unit xcrt;
{ Written by William C. Thompson (wct@po.cwru.edu) - 1991
Parts of this unit were taken from HTScreen, written by
Harold Thunem. }
{ If anyone has an idea for a procedure, please E-mail and I
will consider including it in my unit. It should be something
that you do often. }
(* Features to be added:
Another unit containing definitions for different musical tones *)
{ Designer's Notes:
1. This unit was written was with the goal of making tedious crt
routines much more bearable by modularizing the entire process.
Another goal is to make the routines very fast by directly
affecting memory. Consequently, much of the error checking has
been left out. The user is responsible for error checking his
own code. In many cases this proves to give the user more
control, and there is little or no overhead if the code was
written with some care. For example, many times a rectangle
is defined by (x1,y1) & (x2,y2) which represent the upper-left
and lower-right corners, respectively. If x1>x2 or y1>y2 the
call is often ignored.
2. When setting foreground colors, you can set the blink constant
by adding 128 (pre-defined as 'blink') to the foreground color.
3. As yet, this unit is only designed to handle screens with
80 columns. Including checking for 40 columns would slow
down the procedures which are intended to be very fast.
A program using 40 columns could easily borrow the ideas
used in this unit. I have confirmed that they do work for
43/50 rows. Many don't work for 40 columns.
4. All window-like procedures are in absolute coordinates. Once
again, it up to the user to maintain relative coordinates
somehow (it is not very difficult) because that would slow down
the routines for other uses.
5. My apologies for my somewhat abnormal style of indentation, but
at least it is consistent (unlike some other code I have seen).
You may also notice that I avoid white spaces and capitalization
with a passion. It seems very silly to worry about how many
spaces I have put between variables, so I don't put any unless
absolutely necessary. I do try to keep my commenting neat, when
convenient. }
interface
uses crt,dos,keydef;
const
blackbg=$00;
bluebg=$10;
greenbg=$20;
cyanbg=$30;
redbg=$40;
magentabg=$50;
brownbg=$60;
lightgraybg=$70;
{ Setting the text color and background color at the same time can
be very tedious. You have to say TextColor(X) and TextBackGround(Y),
which is much too much typing. You can also be clever and set
TextAttr:=Y*16+X, which is a pain. This can be made simpler by
setting TextAttr:=YBG+X, which sets the background color at the
same with a minimum of typing. It also lets you avoid trying to
set background colors to 8-15, something that I have tried often.
More importantly, it makes it clearer to see what is happening.
For example, instead of
TextColor(White); TextBackGround(Cyan) or TextAttr:=Cyan*16+White,
much simpler would be
TextAttr:=CyanBG+White.
If you wish to set only the background or foreground color (but
not both), you can still use TextColor and TextBackGround. }
{ Text fonts, 25 or 43/50 rows }
ega43font=1;
normalfont=2;
{ border constants }
noborder=0;
singleborder=1;
doubleborder=2;
dtopsside=3;
stopdside=4;
{ textline constants }
thinhoriz=0;
thinvert=1;
thickhoriz=2;
thickvert=3;
type
screenpt=^screen;
screen=array[0..3999] of word;
{ This is a maximum size for a screen - 80 columns * 50 rows = 4000.
The maximum space required would then be 8000 bytes. }
block=record
rows,cols: word;
sp: screenpt
end;
getoneofstring=string[120];
writexystring=string[80];
var
badkeybeep: boolean; { beep when a bad is pressed? }
badkeyhz: word; { sound to emit for bad key }
badkeydur: word; { duration of bad key beep }
goodkeybeep: boolean; { beep when a good key is pressed }
goodkeyhz: word; { sound to emit for good key }
goodkeydur: word; { duration of good key beep }
cursorinitial, cursoroff, cursorunderline,
cursorhalfblock, cursorblock: word; { cursor settings }
preserveattr: boolean;
{ If preserveattr=true, putch will preserve the attribute settings
for a location on the screen. If preserveattr=false (default),
it will change the color attributes to the setting held in
textattr. }
crtrows, { Number of rows }
crtcols, { Number of columns }
videomode:byte; { Video-mode }
procedure beep(hz,dur: word);
function getch(x,y: byte):char;
function getattr(x,y: byte):byte;
procedure putch(x,y: byte; c: char);
procedure putattr(x,y:byte; attr:byte);
function shadowattr(attr:byte):byte;
procedure writexy(x,y: byte; s: writexystring);
procedure rightjust(x,y: byte; s: writexystring);
procedure centerjust(x,y:byte; s:writexystring);
procedure textbox(x1,y1,x2,y2: word; border:byte);
procedure textline(startat,endat,c:word; attr:byte);
procedure colorblock(x1,y1,x2,y2: word; c:byte);
procedure fillblock(x1,y1,x2,y2:word; ch:char);
procedure shadowblock(x1,y1,x2,y2:word);
procedure attrblock(x1,y1,x2,y2:word; attr:byte);
procedure scrollblockup(x1,y1,x2,y2,wakeattr:byte);
procedure scrollblockdown(x1,y1,x2,y2,wakeattr:byte);
procedure explodeblock(x1,y1,x2,y2:byte);
function readallkeys:char;
function yesorno:char;
function getoneof(s:getoneofstring):char;
function getcursor:word;
procedure setcursor(curs:word);
procedure savewindow(x1,y1,x2,y2: word; var w: block);
procedure killwindow(var w:block);
procedure recallwindow(x1,y1:word; var w: block);
function getfont:byte;
procedure setfont(font:byte);
function getvideomode:byte;
procedure setvideomode(mode:byte);
procedure xcrtinit;
implementation
const
borders:array[0..4] of string[6]=(' ',
'┌─┐│┘└',
'╔═╗║╝╚',
'╒═╕│╛╘',
'╓─╖║╜╙');
var
regs: registers;
videoseg: word; { Video segment address }
procedure beep(hz,dur: word);
begin
sound(hz);
delay(dur);
nosound
end;
function getch(x,y: byte):char;
{ returns character at absolute position (x,y) through memory
The error checking has been removed to speed up function }
begin
getch:=char(mem[videoseg:(160*y+2*x-162)]); { 2*80*(y-1)+2*(x-1) }
end;
function getattr(x,y: byte):byte;
{ returns color attribute at absolute position (x,y) through memory
The error checking has been removed to speed up function }
begin
getattr:=mem[videoseg:(160*y+2*x-161)]; { 2*80*(y-1)+2*(x-1)+1 }
end;
procedure putch(x,y: byte; c: char);
{ QUICKLY writes c to absolute position (x,y) through memory
This is at least 10 times faster than a gotoxy(x,y), write(c)
Another bonus is that the cursor doesn't move.
The error checking has been removed }
begin
if not preserveattr then
memw[videoseg:(160*y+2*x-162)]:=textattr shl 8+ord(c)
else mem[videoseg:(160*y+2*x-162)]:=ord(c)
end;
procedure putattr(x,y,attr: byte);
{ Directly change the color attributes of char at absolute screen (x,y) }
begin
mem[videoseg:(160*y+2*x-161)]:=attr
end;
function shadowattr(attr:byte):byte;
{ Returns an appropriate shadow attribute. First it masks out the
upper four bits (background of shadow is always black) as well as
the 3rd bit (a shadow should be a dark color). Unfortunately,
if the text color is black, you can't see it, so there is a
special case for that (sets it to lightgray). }
var
temp: byte;
begin
temp:=attr and $07;
if temp=black then shadowattr:=lightgray
else shadowattr:=temp
end;
procedure writexy(x,y: byte; s: writexystring);
{ Writes string s at absolute (x,y) - left justified }
var
i: byte;
begin
for i:=1 to length(s) do putch(